﻿using System;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Quartz;
using Volo.Abp.BackgroundWorkers.Quartz;
using Volo.Abp.Domain.Repositories;

namespace Linker.TaskCenter.Services
{
    /// <summary>
    ///     服务健康检查
    /// </summary>
    [DisallowConcurrentExecution]
    public class HealthCheckWorker : QuartzBackgroundWorkerBase
    {
        private readonly IRepository<ServiceEntity, Guid> _repository;

        public HealthCheckWorker(IRepository<ServiceEntity, Guid> repository)
        {
            _repository = repository;
            JobDetail = JobBuilder.Create<HealthCheckWorker>()
                .WithIdentity(nameof(HealthCheckWorker))
                .Build();
            Trigger = TriggerBuilder.Create()
                .WithIdentity(nameof(HealthCheckWorker))
                .StartNow()
                .WithSimpleSchedule(s => s.WithIntervalInSeconds(30).RepeatForever())
                .Build();
        }


        public override async Task Execute(IJobExecutionContext context)
        {
            var services = await _repository.GetListAsync();
            foreach (var service in services.Where(service => !string.IsNullOrEmpty(service.HealthCheckUrl)))
            {
                service.Status = await HealthCheck(service.HealthCheckUrl);
                service.LastHealthyCheckTime = DateTime.Now;
                _repository.UpdateAsync(service);
                Logger.LogInformation($"{service.ServerName}, Status:{service.Status}");
            }
        }


        private async Task<ServiceHealthyEnum> HealthCheck(string url)
        {
            try
            {
                var client = new HttpClient();
                var response = await client.GetAsync(url);
                return response.IsSuccessStatusCode ? ServiceHealthyEnum.Healthy : ServiceHealthyEnum.Unhealthy;
            }
            catch (Exception e)
            {
                Logger.LogError(e.Message);
                return ServiceHealthyEnum.Offline;
            }
        }
    }
}